
#[cfg(test)]
pub mod test_iter {
    
    /* 什么是迭代器
·迭代器模式:对一系列项执行某些任务
·迭代器负责:
- 遍历每个项
- 确定序列(遍历)何时完成
·Rust 的迭代器:
- 懒惰的:除非调用消费迭代器的方法，否则迭代器本身没有任何效果。 */
    #[test]
    fn iter01() {
        let v1 = vec![1, 2, 3];
        let v1_ite = v1.iter();
        
        for v in v1_ite {
            println!("{}", v);
        }
    }

    /* 
Iterator trait
·所有迭代器都实现了Iterator trait
·lterator trait定义于标准库，定义大致如下:
. pub trait Iterator {
type ltem;
fn next(&mut self) -> Option<Self::Item>;
// methods with default implementations elided
}
·type ltem 和Self::Item定义了与此该trait关联的类型。
- 实现Iterator trait需要你定义一个Item类型，它用于next方法的返回类型(迭代器的
返回类型)。*/

    /* lterator trait
·Iterator trait仅要求实现一个方法:next
.next:
- 每次返回迭代器中的一项
- 返回结果包裹在Some 里
- 迭代结束，返回None
·可直接在迭代器上调用next方法
    */
    #[test]
    fn iter02() {
        let v1 = vec![1, 2, 3];
        let mut v1_ite = v1.iter();

        match v1_ite.next() {
            Some(v) => println!("{}", v),
            None => println!("is null"),
        }

        match v1_ite.next() {
            Some(v) => println!("{}", v),
            None => println!("is null"),
        }
    }

    /* 几个迭代方法
    ·iter 方法:在不可变引用上创建迭代器
    ·into_iter方法:创建的迭代器会获得所有权
    ·iter_mut方法:迭代可变的引用
    */
    /* 消耗迭代器的方法
    ·在标准库中，Iterator trait有一些带默认实现的方法
    ·其中有一些方法会调用next方法
    - 实现Iterator trait时必须实现next方法的原因之一
    ·调用next的方法叫做“消耗型适配器”
    - 因为调用它们会把迭代器消耗尽
    ·例如:sum方法(就会耗尽迭代器)
    - 取得迭代器的所有权
    - 通过反复调用next，遍历所有元素
    - 每次迭代，把当前元素添加到一个总和里，迭代结束，返回总和
    */
    #[test]
    fn iter03() {
        let v1 = vec![1, 2, 3];
        let mut v1_ite = v1.iter();
        let sum: i32 = v1_ite.sum();
        println!("{}", sum);
    }

    /* 产生其它迭代器的方法
·定义在 Iterator trait上的另外一些方法叫做“迭代器适配器”
- 把迭代器转换为不同种类的迭代器
·可以通过链式调用使用多个迭代器适配器来执行复杂的操作，这种调用可读性较高。
·例如:map
- 接收一个闭包，闭包作用于每个元素
-产生一个新的迭代器

·collect方法:消耗型适配器，把结果收集到一个集合类型中。
 */
    #[test]
    fn iter04() {
        let v1 = vec![1, 2, 3];
        let v2: Vec<_> = v1.iter().map(|x| x+1).collect();
        println!("{}", v2[0]);
    }

    /* 
使用闭包捕获环境
·filter 方法:
- 接收一个闭包
- 这个闭包在遍历迭代器的每个元素时，返回bool类型
- 如果闭包返回true:当前元素将会包含在filter产生的迭代器中
- 如果闭包返回false:当前元素将不会包含在filter产生的迭代器中 */
    #[test]
    fn iter05() {
        let v1 = vec![1, 2, 3, 6, 113, 514, 13, 42, 425];
        let v2: Vec<_> = v1.into_iter().filter(|x| x%2 == 0).collect();

        for v in v2.iter() {
            println!("{}", v);
        }
    }

    /* 使用 Iterator trait来创建自定义迭代器
·实现 next方法 */
    struct Counter {
        count: u32,
    }
    impl Counter {
        fn new(count: u32) -> Counter {
            Counter{ count }
        }
    }
    impl Iterator for Counter {
        type Item = u32;
        fn next(&mut self) -> Option<Self::Item> {
            if self.count < 10 {
                self.count += 1;
                Some(self.count)
            } else {
                None
            }
        }   
    }
    #[test]
    fn iter06() {
        let mut c = Counter::new(2);
        for i in 0..10 {
            match c.next() {
                Some(v) => println!("c = {}", v),
                None => println!("c = None"),
            }                
        }

        let c2: u32 = Counter::new(3)
            // 一般用于将两个集合组成元组
            .zip(Counter::new(1))
            .map(|(a, b)| a * b)
            .filter(|x| x %4 == 0)
            .sum();
        println!("c2 = {}", c2);
    }

    /* 一个测试
·把一本小说的内容放在一个String 里面，搜索“the”:
test bench_search_for  ... bench: 19,620,300 ns/iter (+/- 915,700)
test bench_search_iter ... bench: 19,234,900 ns/iter (+/- 657,200)
·迭代器的版本更快一点! */
}
